
//
// 110405 - AH - (Zen *) Created.
// 110423 - AH - No more direct access to ontology on SoekratEngine, must
//               use getWheel() first to get.
//

package org.soekrat.engine.pitbul.parser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.soekrat.engine.Soekrat2Engine;
import org.soekrat.engine.forest.Tree;
import org.soekrat.engine.mine.Mine;
import org.soekrat.engine.mine.Resource;
import org.soekrat.engine.mine.Tags;

/**
 /**
 * <p>
 *   {@link FormParser} for the <i>resource</i> form.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC)  
 */
public final class ResourceFormParser extends FormParser 
{
  /**
   * <p>
   *   Constructor.
   * </p>
   */
  public ResourceFormParser(){ super("resource"); } 
  
  private static enum State
  {
    START, PRE_CUE_TOKENS, CUE, POST_CUE_TOKENS, END
  };
  
  //private final List<String> m_tokens=new ArrayList<String>();

  @Override
  public void parse(Tree tree, Soekrat2Engine se) throws IOException 
  {
    if (tree==null)
    {
      throw new NullPointerException("tree");
    }
    if (se==null)
    {
      throw new NullPointerException("se");
    }
    
    PitbulTokens tokens=(PitbulTokens)tree.getAttribute("post-tokens");
    
    List<String> nodes=new ArrayList<String>();
    
    List<String> tags=new ArrayList<String>();
    
    List<String> argTokens=new ArrayList<String>();
  
    State state=State.START;
    
    int idx=1; 
    
    String token="";
    
    boolean center=false;
    
    while (true)
    {
      switch (state)
      {
        case START :
          
          token=getExpectedToken(tokens, idx++, "*be");
          
          if (tokens.passedEnd(idx)) state=State.END;          
          else                       state=State.PRE_CUE_TOKENS;
          
        break;
        
        case PRE_CUE_TOKENS :
          
          token=getToken(tokens, idx++);
          
          if (isCue(token))
          {
            if (tokens.passedEnd(idx)) state=State.END;
                                       state=State.CUE;  
          }
          else
          {
            argTokens.add(token);
            if (tokens.passedEnd(idx)) state=State.END;
          }
          
        break;
        
        case POST_CUE_TOKENS :
          
          token=getToken(tokens, idx++);
          
          argTokens.add(token);
          
          if (tokens.passedEnd(idx)) state=State.END;
          
        break;
        
        case CUE :
          
          if (argTokens.isEmpty())
          {
            throw new IOException("missing tokens for cue: "+token);
          }
          
          if (token.equals("#center"))
          {
            nodes.addAll(argTokens);
            center=true;
          }
          else if (token.equals("#around"))
          {
            tags.addAll(argTokens);
            center=false;
          }
          else
          {
            throw new IOException("uknown resource from cue: "+token);
          }
          
          argTokens.clear();
          
          if (tokens.passedEnd(idx)) state=State.END;
          else                       state=State.POST_CUE_TOKENS;
          
        break;
        
        case END :
          
          if (center)
          {
            tags.addAll(argTokens);  
          }
          else
          {
            nodes.addAll(argTokens);
          }
          
          System.out.println("nodes: "+nodes);
          System.out.println("tags: "+tags);
          System.out.println();
          
          Mine mine=se.getWheel().getMine();
          for (String node : nodes) 
          {
            Tags tgs=new Tags(tags);
            
            Resource resource=new Resource(node);
            
            mine.add(resource, tgs);
          }

        return;

      }
          
    }
  }
  
  private static boolean isCue(String token)
  {
    return token.length()>0 && token.charAt(0)=='#';
  }
  
}
